package com.spotify.analysis.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spotify.analysis.dto.TrackRequestParam;
import com.spotify.analysis.entity.*;
import com.spotify.analysis.mapper.*;
import com.spotify.analysis.service.TrackService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Service
@Slf4j
public class TrackServiceImpl extends ServiceImpl<TrackMapper, Track> implements TrackService {

    @Autowired
    private KeyMapper keyMapper;
    @Autowired
    private DanceabilityMapper danceabilityMapper;
    @Autowired
    private EnergyMapper energyMapper;
    @Autowired
    private GenreMapper genreMapper;

    @Override
    public IPage<Track> getTracks(TrackRequestParam param) {
        log.info("getTracks: start:{}, end:{}, genres:{}, keys:{}, page:{}, pageSize:{}", param.getStart(), param.getEnd(), param.getGenres(), param.getKeys(), param.getPage(), param.getPageSize());
        QueryWrapper<Track> queryWrapper = buildQueryWrapper(param);

        Integer page = param.getPage();
        Integer pageSize = param.getPageSize();
        Page<Track> pageObj = new Page<>(page != null ? page : 1, pageSize != null ? pageSize : 10, true);
        return this.page(pageObj, queryWrapper);
    }

    @Override
    public Track getTrackById(String id) {
        QueryWrapper<Track> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("track_id", id);
        return this.getOne(queryWrapper);
    }

    @Override
    public Map<String, Object> getGenres() {
        List<String> genres = this.list().stream()
                .map(Track::getGenre)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());

        Map<String, Object> result = new HashMap<>();
        result.put("total", genres.size());
        result.put("list", genres);
        return result;
    }

    @Override
    public Map<String, Object> getKeys() {
        List<Integer> keys = this.list().stream()
                .map(Track::getKey)
                .filter(Objects::nonNull)
                .distinct()
                .sorted()
                .collect(Collectors.toList());

        Map<String, Object> result = new HashMap<>();
        result.put("total", keys.size());
        result.put("list", keys);
        return result;
    }

//    @Override
//    public Map<String, Object> getKeyDistribution(TrackRequestParam param) {
//        QueryWrapper<Track> queryWrapper = buildQueryWrapper(param);
//        List<Track> tracks = this.list(queryWrapper);
//
//        Map<Integer, Long> keyCountMap = tracks.stream()
//                .collect(Collectors.groupingBy(Track::getKey, Collectors.counting()));
//
//        List<Map<String, Object>> list = keyCountMap.entrySet().stream()
//                .map(entry -> {
//                    Map<String, Object> item = new HashMap<>();
//                    item.put("key", entry.getKey());
//                    item.put("num", entry.getValue());
//                    return item;
//                })
//                .collect(Collectors.toList());
//
//        Map<String, Object> result = new HashMap<>();
//        result.put("total", tracks.size());
//        result.put("list", list);
//        return result;
//    }

//    @Override
//    public Map<String, Object> getKeyDistribution(TrackRequestParam param) {
//        // 构建针对Key表的查询条件
//        QueryWrapper<Key> queryWrapper = buildKeyQueryWrapper(param);
//        // 从Key表查询数据
//        List<Key> keys = keyMapper.selectList(queryWrapper);
//
//        // 统计key字段的分布情况
//        Map<Integer, Long> keyCountMap = keys.stream()
//                .collect(Collectors.groupingBy(Key::getKey, Collectors.counting()));
//
//        // 转换结果格式
//        List<Map<String, Object>> list = keyCountMap.entrySet().stream()
//                .map(entry -> {
//                    Map<String, Object> item = new HashMap<>();
//                    item.put("key", entry.getKey());
//                    item.put("num", entry.getValue());
//                    return item;
//                })
//                .collect(Collectors.toList());
//
//        Map<String, Object> result = new HashMap<>();
//        result.put("total", keys.size());
//        result.put("list", list);
//        return result;
//    }
// ===================== 核心修改：getKeyDistribution（按key分组累加num） =====================
@Override
public Map<String, Object> getKeyDistribution(TrackRequestParam param) {
    // 1. 构建查询条件：按参数中的年份范围（如2001-2003）筛选Key表数据
    QueryWrapper<Key> queryWrapper = buildKeyQueryWrapper(param);
    List<Key> keyList = keyMapper.selectList(queryWrapper);

    // 2. 核心逻辑：按key分组，累加同一key下所有年份的num值
    // 结果：Map<key值, 该key的num总和>
    Map<Integer, Long> keyNumSumMap = keyList.stream()
            .filter(key -> key.getNum() != null && key.getKey() != null) // 过滤num/key为null的无效数据
            .collect(Collectors.groupingBy(
                    Key::getKey, // 分组依据：Key表的key字段
                    Collectors.summingLong(Key::getNum) // 分组后操作：累加该组的num字段（用Long避免溢出）
            ));

    // 3. 转换为返回格式：每个item包含"key"和"num"（num为累加后的值）
    List<Map<String, Object>> distributionList = keyNumSumMap.entrySet().stream()
            .map(entry -> {
                Map<String, Object> item = new HashMap<>();
                item.put("key", entry.getKey()); // 分组的key值
                item.put("num", entry.getValue()); // 该key的num累加总和
                return item;
            })
            .sorted(Comparator.comparingInt(item -> (Integer) item.get("key"))) // 可选：按key升序排序，便于前端展示
            .collect(Collectors.toList());

    // 4. 构建最终返回结果
    Map<String, Object> result = new HashMap<>();
    result.put("total", keyList.size()); // 符合条件的Key表总记录数（可保留，也可改为key的去重数量）
    result.put("yearRange", param.getStart() + "-" + param.getEnd()); // 可选：返回当前统计的年份范围，便于前端显示
    result.put("list", distributionList); // 按key分组累加后的分布数据
    return result;
}

//    @Override
//    public Map<String, Object> getGenreDistribution(TrackRequestParam param) {
//        QueryWrapper<Track> queryWrapper = buildQueryWrapper(param);
//        List<Track> tracks = this.list(queryWrapper);
//
//        Map<String, Long> genreCountMap = tracks.stream()
//                .collect(Collectors.groupingBy(Track::getGenre, Collectors.counting()));
//
//        List<Map<String, Object>> list = genreCountMap.entrySet().stream()
//                .map(entry -> {
//                    Map<String, Object> item = new HashMap<>();
//                    item.put("genre", entry.getKey());
//                    item.put("num", entry.getValue());
//                    return item;
//                })
//                .collect(Collectors.toList());
//
//        Map<String, Object> result = new HashMap<>();
//        result.put("total", tracks.size());
//        result.put("list", list);
//        return result;
//    }
// ---------------------- 2. 修改：Genre分布（按genre分组累加num） ----------------------
@Override
public Map<String, Object> getGenreDistribution(TrackRequestParam param) {
    // 构建Genre表的查询条件（按年份、指定genre筛选）
    QueryWrapper<Genre> queryWrapper = buildGenreQueryWrapper(param);
    List<Genre> genreList = genreMapper.selectList(queryWrapper);

    // 按genre分组，累加num（注意genre是String类型）
    Map<String, Long> genreNumSumMap = genreList.stream()
            .filter(genre -> genre.getNum() != null && genre.getGenre() != null)
            .collect(Collectors.groupingBy(
                    Genre::getGenre,
                    Collectors.summingLong(Genre::getNum)
            ));

    // 转换返回格式（按num降序排序，热门genre在前）
    List<Map<String, Object>> distributionList = genreNumSumMap.entrySet().stream()
            .map(entry -> {
                Map<String, Object> item = new HashMap<>();
                item.put("genre", entry.getKey()); // 音乐流派
                item.put("num", entry.getValue()); // 累加后的数量
                return item;
            })
            .sorted((item1, item2) -> Long.compare((Long) item2.get("num"), (Long) item1.get("num")))
            .collect(Collectors.toList());

    Map<String, Object> result = new HashMap<>();
    result.put("totalRecords", genreList.size());
    result.put("yearRange", getYearRangeStr(param));
    result.put("list", distributionList);
    return result;
}

//    @Override
//    public Map<String, Object> getEnergyDistribution(TrackRequestParam param) {
//        QueryWrapper<Track> queryWrapper = buildQueryWrapper(param);
//        List<Track> tracks = this.list(queryWrapper);
//
//        // 创建10个区间，每个区间10%
//        int[] energyRanges = new int[10];
//        for (Track track : tracks) {
//            if (track.getEnergy() != null) {
//                int index = Math.min(track.getEnergy() / 10, 9);
//                energyRanges[index]++;
//            }
//        }
//
//        List<Integer> list = IntStream.of(energyRanges).boxed().collect(Collectors.toList());
//
//        Map<String, Object> result = new HashMap<>();
//        result.put("total", tracks.size());
//        result.put("list", list);
//        return result;
//    }
// ===================== 1. 修改：Energy分布（从Energy表拿数据，按区间累加num） =====================
@Override
public Map<String, Object> getEnergyDistribution(TrackRequestParam param) {
    // 1. 构建Energy表的查询条件（按年份筛选，与原逻辑一致）
    QueryWrapper<Energy> queryWrapper = buildEnergyQueryWrapper(param);
    // 2. 从Energy表查询符合条件的所有数据
    List<Energy> energyList = energyMapper.selectList(queryWrapper);

    // 3. 核心：创建10个区间，累加每个区间的num值（原逻辑是计数，现在改为求和）
    int[] energyRangeSum = new int[10]; // 用long避免num累加溢出
    for (Energy energy : energyList) {
        // 过滤无效数据（energy值或num为null时跳过）
        if (energy.getEnergy() == null || energy.getNum() == null) {
            continue;
        }
        // 计算区间索引：0-10→0，11-20→1，...，91-100→9（与原逻辑一致）
        int index = Math.min(energy.getEnergy() / 10, 9);
        // 累加当前记录的num到对应区间（原逻辑是energyRangeSum[index]++，现在改为累加num）
        energyRangeSum[index] += energy.getNum();
    }

    // 4. 转换为返回格式（保持原逻辑的List<Integer>，若num可能超int则改为List<Long>）
    List<Integer> list = IntStream.of(energyRangeSum).boxed().collect(Collectors.toList());
    // 若前端只能接收Integer，且确认num累加不会超int范围，可改为：
    // List<Integer> list = IntStream.of(energyRangeSum).mapToObj(Long::intValue).collect(Collectors.toList());

    // 5. 构建返回结果（保持原字段名，确保前端兼容）
    Map<String, Object> result = new HashMap<>();
    result.put("total", energyList.size()); // 符合条件的Energy表总记录数（与原逻辑一致）
    result.put("list", list); // 10个区间的num累加结果（核心修改点）
    result.put("yearRange", getYearRangeStr(param)); // 可选：增加年份范围描述，便于前端展示
    return result;
}


//    @Override
//    public Map<String, Object> getDanceabilityDistribution(TrackRequestParam param) {
//        QueryWrapper<Track> queryWrapper = buildQueryWrapper(param);
//        List<Track> tracks = this.list(queryWrapper);
//
//        // 创建10个区间，每个区间10%
//        int[] danceabilityRanges = new int[10];
//        for (Track track : tracks) {
//            if (track.getDanceability() != null) {
//                int index = Math.min(track.getDanceability() / 10, 9);
//                danceabilityRanges[index]++;
//            }
//        }
//
//        List<Integer> list = IntStream.of(danceabilityRanges).boxed().collect(Collectors.toList());
//
//        Map<String, Object> result = new HashMap<>();
//        result.put("total", tracks.size());
//        result.put("list", list);
//        return result;
//    }
// ===================== 2. 修改：Danceability分布（从Danceability表拿数据，按区间累加num） =====================
@Override
public Map<String, Object> getDanceabilityDistribution(TrackRequestParam param) {
    // 1. 构建Danceability表的查询条件（按年份筛选，与原逻辑一致）
    QueryWrapper<Danceability> queryWrapper = buildDanceabilityQueryWrapper(param);
    // 2. 从Danceability表查询符合条件的所有数据
    List<Danceability> danceabilityList = danceabilityMapper.selectList(queryWrapper);

    // 3. 核心：创建10个区间，累加每个区间的num值（与Energy逻辑完全对齐）
    int[] danceRangeSum = new int[10]; // 用long避免溢出
    for (Danceability dance : danceabilityList) {
        // 过滤无效数据（danceability值或num为null时跳过）
        if (dance.getDanceability() == null || dance.getNum() == null) {
            continue;
        }
        // 计算区间索引（与原逻辑一致：0-10→0，...，91-100→9）
        int index = Math.min(dance.getDanceability() / 10, 9);
        // 累加当前记录的num到对应区间
        danceRangeSum[index] += dance.getNum();
    }

    // 4. 转换为返回格式（与Energy保持一致）
    List<Integer> list = IntStream.of(danceRangeSum).boxed().collect(Collectors.toList());
    // 若前端需Integer：List<Integer> list = IntStream.of(danceRangeSum).mapToObj(Long::intValue).collect(Collectors.toList());

    // 5. 构建返回结果（保持原字段名，前端无需修改）
    Map<String, Object> result = new HashMap<>();
    result.put("total", danceabilityList.size()); // 符合条件的Danceability表总记录数
    result.put("list", list); // 10个区间的num累加结果
    result.put("yearRange", getYearRangeStr(param)); // 可选：年份范围描述
    return result;
}

    private QueryWrapper<Track> buildQueryWrapper(TrackRequestParam param) {
        Integer start = param.getStart();
        Integer end = param.getEnd();
        List<String> genres = param.getGenres();
        List<String> keys = param.getKeys();
        Integer page = param.getPage();
        Integer pageSize = param.getPageSize();
        QueryWrapper<Track> queryWrapper = new QueryWrapper<>();

        if (start != null) {
            queryWrapper.ge("year", start);
        }

        if (end != null) {
            queryWrapper.le("year", end);
        }

        if (genres != null && !genres.isEmpty()) {
            queryWrapper.in("genre", genres);
        }

        if (keys != null && !keys.isEmpty()) {
            List<Integer> keyValues = keys.stream().map(Integer::parseInt).collect(Collectors.toList());
            queryWrapper.in("`key`", keyValues);
        }

        return queryWrapper;
    }

    // 为Key表构建查询条件
    private QueryWrapper<Key> buildKeyQueryWrapper(TrackRequestParam param) {
        Integer start = param.getStart();
        Integer end = param.getEnd();
        List<String> keys = param.getKeys();
        QueryWrapper<Key> queryWrapper = new QueryWrapper<>();

        // Key表有year字段，可以使用年份筛选
        if (start != null) {
            queryWrapper.ge("year", start);
        }

        if (end != null) {
            queryWrapper.le("year", end);
        }

        // 筛选特定的key值
        if (keys != null && !keys.isEmpty()) {
            List<Integer> keyValues = keys.stream().map(Integer::parseInt).collect(Collectors.toList());
            queryWrapper.in("`key`", keyValues);
        }

        return queryWrapper;
    }

    private QueryWrapper<Genre> buildGenreQueryWrapper(TrackRequestParam param) {
        QueryWrapper<Genre> queryWrapper = new QueryWrapper<>();
        // 年份范围筛选
        if (param.getStart() != null) queryWrapper.ge("year", param.getStart());
        if (param.getEnd() != null) queryWrapper.le("year", param.getEnd());
        // 支持按指定genre筛选（如传入["pop","rock"]只统计这两个流派）
        if (param.getGenres() != null && !param.getGenres().isEmpty()) {
            queryWrapper.in("genre", param.getGenres());
        }
        return queryWrapper;
    }

    /** 构建Energy表的查询条件（按年份筛选，与原Track表逻辑对齐） */
    private QueryWrapper<Energy> buildEnergyQueryWrapper(TrackRequestParam param) {
        QueryWrapper<Energy> queryWrapper = new QueryWrapper<>();
        // 年份范围筛选（原逻辑的start/end参数复用）
        if (param.getStart() != null) {
            queryWrapper.ge("year", param.getStart()); // 大于等于开始年份
        }
        if (param.getEnd() != null) {
            queryWrapper.le("year", param.getEnd()); // 小于等于结束年份
        }
        // 可选：若需按特定energy值筛选，可增加以下逻辑（需在TrackRequestParam加energies字段）
        // if (param.getEnergies() != null && !param.getEnergies().isEmpty()) {
        //     List<Integer> energyValues = param.getEnergies().stream().map(Integer::parseInt).collect(Collectors.toList());
        //     queryWrapper.in("energy", energyValues);
        // }
        return queryWrapper;
    }

    /** 构建Danceability表的查询条件（按年份筛选，与原Track表逻辑对齐） */
    private QueryWrapper<Danceability> buildDanceabilityQueryWrapper(TrackRequestParam param) {
        QueryWrapper<Danceability> queryWrapper = new QueryWrapper<>();
        // 年份范围筛选（复用原start/end参数）
        if (param.getStart() != null) {
            queryWrapper.ge("year", param.getStart());
        }
        if (param.getEnd() != null) {
            queryWrapper.le("year", param.getEnd());
        }
        // 可选：若需按特定danceability值筛选，可增加以下逻辑（需在TrackRequestParam加danceabilities字段）
        // if (param.getDanceabilities() != null && !param.getDanceabilities().isEmpty()) {
        //     List<Integer> danceValues = param.getDanceabilities().stream().map(Integer::parseInt).collect(Collectors.toList());
        //     queryWrapper.in("danceability", danceValues);
        // }
        return queryWrapper;
    }

    /** 辅助：生成年份范围描述（如"2001-2003"或"2001至今"） */
    private String getYearRangeStr(TrackRequestParam param) {
        if (param.getStart() == null && param.getEnd() == null) {
            return "全部年份";
        } else if (param.getStart() != null && param.getEnd() == null) {
            return param.getStart() + "至今";
        } else if (param.getStart() == null && param.getEnd() != null) {
            return "至" + param.getEnd();
        } else {
            return param.getStart() + "-" + param.getEnd();
        }
    }
}